home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / SRS / server / src / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-12  |  25.1 KB  |  1,010 lines

  1. /* This contains functions to send and receive data from the server */
  2. /* ---------------------------------------------------------------- */
  3.  
  4. #include "headers.h" /* has all important stuff */
  5.  
  6. /* This file has the server I/O functions.. to communicate with server */
  7.  
  8. /* send data to server */
  9. void send_data(int fd, char *fmt, ...)
  10. {
  11.    int res;
  12.    int ch = 0;
  13.    int size = 2;
  14.  
  15. #  ifndef NOSSL
  16.    int sslerr = 0;
  17.    int dobreak = 0;
  18. #  endif
  19.  
  20.    va_list args;
  21.  
  22.    char *lnptr, *cmdptr;
  23.    char writebuf[MAXWRITESIZE];
  24.    
  25.    errors = 0;
  26.  
  27.    memset(writebuf, 0, sizeof(writebuf));
  28.    memset(clients[curClient].logmsg.cmdmsg, 0, MAXSEGSIZE);
  29.  
  30.    va_start(args, fmt);
  31.    (void)vsnprintf(writebuf, sizeof(writebuf) - 1, fmt, args);
  32.    va_end(args);
  33.     
  34.    (void)strncpy(clients[curClient].logmsg.cmdmsg, writebuf, MAXSEGSIZE - 1);
  35.    clients[curClient].logmsg.cmdlen = strlen(clients[curClient].logmsg.cmdmsg);
  36.  
  37.    if (child == 1)
  38.    {
  39.       if (getpid() == clients[curClient].pidstats[0].pid) ch = 0;
  40.       else ch = 1;
  41.    }
  42.  
  43.    if (((writebuf[0] == '\n') || (writebuf[0] == '\0')) && 
  44.        (isprint(writebuf[1]) == 0))
  45.    {
  46. #     ifdef NOSSL
  47.       if (silent != 1)
  48.       {
  49.          if (child == 1)
  50.             debug("[in recv_data] (in %s)\n"
  51.                   "the data received is bad.. returning\n\n",
  52.                   (ch == 1 ? "child" : "parent"));
  53.  
  54.          else
  55.             debug("(in recv_data) the data received is bad.. "
  56.                   "returning\n\n");
  57.  
  58.          debug("bad data is:\n%s\n", readbuf);
  59.       }
  60.  
  61. #     else
  62.       error("client possibly disconnected.. aborting\n\n");
  63.  
  64.       if (mainpid != getpid()) quit(ERROR);
  65.       else 
  66.       {
  67.          errors = 1;
  68.          longjmp(newconn, 1);
  69.       }
  70. #     endif
  71.  
  72.       return;
  73.    }
  74.  
  75.    if (silent != 1)
  76.    {
  77.       if (strlen(writebuf) <= 12)
  78.          debug("sending the following to the client: %s%c", 
  79.                writebuf, (strchr(writebuf, '\n') == NULL ? '\n' : '\0'));
  80.  
  81.       else
  82.          debug("sending the following to the client:\n%s\n%c", 
  83.                writebuf, (strchr(writebuf, '\n') == NULL ? '\n' : '\0'));
  84.    }
  85.  
  86.    errno = errors = 0;
  87.  
  88.    cmdptr = clients[curClient].logmsg.cmdmsg;
  89.    lnptr = exportInt(clients[curClient].logmsg.cmdlen);
  90.  
  91.    size = 2;
  92.    while(1) 
  93.    {
  94.       errno = 0, res = 0;
  95.  
  96. #     ifndef NOSSL
  97.       res = SSL_write(clients[curClient].sslconn, lnptr, (u_int)size);
  98. #     else
  99.       res = write(clients[curClient].sockfd, lnptr, size);
  100. #     endif
  101.  
  102.       /* ---------------------- */
  103.  
  104. #     ifndef NOSSL /* SSL error handling */
  105.       sslerr = SSL_get_error(clients[curClient].sslconn, res);
  106.       switch(sslerr)
  107.       {
  108.          case SSL_ERROR_NONE:
  109.             if (size == res) 
  110.             {
  111.                dobreak = 1;
  112.                break;
  113.             }
  114.  
  115.             lnptr += res, size -= res;
  116.             break;
  117.  
  118.          case SSL_ERROR_WANT_WRITE:
  119.          case SSL_ERROR_WANT_READ:
  120.          case SSL_ERROR_WANT_X509_LOOKUP:
  121.             errors = 1, dobreak = 1;
  122.             break;
  123.  
  124.          case SSL_ERROR_SYSCALL:
  125.          case SSL_ERROR_SSL:
  126.             errors = 1, dobreak = 1;
  127.             break;
  128.  
  129.          case SSL_ERROR_ZERO_RETURN:
  130.             errors = 1, dobreak = 1;
  131.             break;         
  132.       }
  133.  
  134.       if (dobreak == 1)
  135.       {
  136.          dobreak = 0;
  137.          break;
  138.       }
  139.  
  140. #     else /* normal error handling */
  141.       if (res <= 0)
  142.       {
  143.          if ((res == ERROR) && (errno == EINTR)) continue;
  144.  
  145.          errors = 1;
  146.          break;
  147.       }
  148.  
  149.       else if (res < size)
  150.       {
  151.          lnptr += res, size -= res;
  152.          continue;
  153.       }
  154.  
  155.       else break;
  156. #     endif /* SSL/NOSSL error handling part */
  157.    }
  158.  
  159.    if (errors != 1)
  160.    {
  161.       size = clients[curClient].logmsg.cmdlen;
  162.  
  163.       while(1)
  164.       {
  165.          errno = 0, res = 0;
  166.  
  167. #        ifndef NOSSL
  168.          SSL_write(clients[curClient].sslconn, cmdptr, (u_int)size);
  169. #        else
  170.          res = write(clients[curClient].sockfd, cmdptr, size);
  171. #        endif
  172.  
  173.          /* ---------------------- */
  174.  
  175. #        ifndef NOSSL /* SSL error handling */
  176.          sslerr = SSL_get_error(clients[curClient].sslconn, res);
  177.          switch(sslerr)
  178.          {
  179.             case SSL_ERROR_NONE:
  180.                if (size == res) 
  181.                {
  182.                   dobreak = 1;
  183.                   break;
  184.                }
  185.  
  186.                cmdptr += res, size -= res;
  187.                break;
  188.  
  189.             case SSL_ERROR_WANT_WRITE:
  190.             case SSL_ERROR_WANT_READ:
  191.             case SSL_ERROR_WANT_X509_LOOKUP:
  192.                errors = 1, dobreak = 1;
  193.                break;
  194.  
  195.             case SSL_ERROR_SYSCALL:
  196.             case SSL_ERROR_SSL:
  197.                errors = 1, dobreak = 1;
  198.                break;
  199.  
  200.             case SSL_ERROR_ZERO_RETURN:
  201.                errors = 1, dobreak = 1;
  202.                break;         
  203.          }
  204.  
  205.          if (dobreak == 1)
  206.          {
  207.             dobreak = 0;
  208.             break;
  209.          }
  210.  
  211. #        else /* normal error handling */
  212.          if (res <= 0)
  213.          {
  214.             if ((res == ERROR) && (errno == EINTR)) continue;
  215.  
  216.             errors = 1;
  217.             break;
  218.          }
  219.  
  220.          else if (res < size)
  221.          {
  222.             cmdptr += res, size -= res;
  223.             continue;
  224.          }
  225.  
  226.          else break;
  227. #        endif /* SSL/NOSSL error handling */
  228.       }
  229.    }
  230.  
  231. #  ifndef NOSSL /* SSL error handling part */
  232.    switch(sslerr)
  233.    {
  234.       case SSL_ERROR_NONE:
  235.          /* we don't need to do anything for this */
  236.          break;
  237.  
  238.       case SSL_ERROR_WANT_WRITE:
  239.       case SSL_ERROR_WANT_READ:
  240.       case SSL_ERROR_WANT_X509_LOOKUP:
  241.          error("got SSL_ERROR_WANT_(WRITE/READ/X509_LOOKUP).. ignoring\n\n");
  242.          errors = 0;
  243.  
  244.          break;
  245.  
  246.       case SSL_ERROR_SYSCALL:
  247.       case SSL_ERROR_SSL:
  248.          if (errno <= 0)
  249.          { 
  250.             errors = 0;
  251.             break;
  252.          }
  253.  
  254.          error("error with SSL_write: %s\n\n", strerror(errno));
  255.  
  256.          ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  257.          if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  258.  
  259.          if (mainpid != getpid()) quit(ERROR);
  260.          else
  261.          {
  262.             errors = 1, timeout = 0;
  263.             longjmp(newconn, 1);
  264.          }
  265.  
  266.       case SSL_ERROR_ZERO_RETURN:
  267.          if (mainpid != getpid())
  268.          {
  269.             error("client dropped connection.. aborting\n\n");
  270.             quit(ERROR);
  271.          }
  272.  
  273.          else
  274.          {
  275.             error("client dropped connection.. restarting\n\n");
  276.  
  277.             errors = 1, timeout = 0;
  278.             longjmp(newconn, 1);
  279.          }
  280.    }
  281.  
  282. #  else /* no SSL normal error handling */
  283.  
  284.    if (res <= 0)
  285.    {
  286.       if (res == 0)
  287.       {
  288.          if (getpid() != mainpid) 
  289.          {
  290.             error("the client disconnected.. aborting\n\n");
  291.             quit(ERROR);
  292.          }
  293.  
  294.          else
  295.          {
  296.             errors = 1;
  297.             error("the client disconnected.. restarting\n\n");
  298.  
  299.             longjmp(newconn, 1);
  300.          }
  301.       }
  302.  
  303.       else if (errno > 0)
  304.       {
  305.          if (child == 1)
  306.          {
  307. #           ifndef NOSSL
  308.             ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  309.             if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  310.  
  311.             else
  312.                error("(in %s) error sending data to client:\n%s\n\n",
  313.                      (ch == 1 ? "child" : "parent"), strerror(errno));
  314.  
  315. #           else
  316.             error("(in %s) error sending data to client:\n%s\n\n",
  317.                   (ch == 1 ? "child" : "parent"), strerror(errno));
  318. #           endif
  319.          }
  320.  
  321.          else
  322.          {
  323. #           ifndef NOSSL
  324.             ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  325.             if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  326.  
  327. #           else
  328.             error("error sending data to client:\n%s\n\n", strerror(errno));
  329. #           endif
  330.  
  331.          }
  332.  
  333.          if (mainpid != getpid()) quit(ERROR);
  334.          else
  335.          {
  336.             errors = 1;
  337. /*
  338.             if (errno != EPIPE) 
  339.                send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  340. */
  341.  
  342.             longjmp(newconn, 1);
  343.          }
  344.       }
  345.  
  346.       else if ((timeout == 1) || (errors == 1))
  347.       {
  348.          if (silent != 1)
  349.          {
  350. #           ifndef NOSSL
  351.             ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  352.             if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  353.  
  354. #           else
  355.             debug("(in send_data) error or timeout occured sending data\n");
  356. #           endif
  357.          }
  358.  
  359.          errors = 1, timeout = 0;
  360.  
  361.          if (getpid() != mainpid) quit(ERROR);
  362.          else
  363.          {
  364.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  365.             longjmp(newconn, 1);
  366.          }
  367.       }
  368.    }
  369. #  endif /* SSL/NOSSL (error checking part) */
  370.  
  371. /*
  372.    if (strncmp(writebuf, "OKAY", 4) != 0)
  373.    {
  374.       signal(SIGALRM, okayTimeout);
  375.       (void)alarm(MAXPAUSE);
  376.  
  377.       * silent = 1, * getOkay(), silent = 0;
  378.       (void)alarm(0);
  379.  
  380.       if ((errors == 1) || (timeout == 1))
  381.       {
  382.          child = 0;
  383.          send_data(clients[curClient].sockfd, "ERROR: %s\n", CMDACKERROR);
  384.  
  385.          if (mainpid != getpid()) quit(ERROR);
  386.          else
  387.          {
  388.             errors = 1, timeout = 0;
  389.             longjmp(newconn, 1);
  390.          }
  391.       }
  392.    }
  393. */
  394. }
  395.  
  396.    
  397. /* --------------------------------- */
  398.    
  399.  
  400. /* gets new data from server */
  401. /* [all recv_data() calls must pass sizeof()-1] */
  402. void recv_data(int fd, char *readbuf, int len, int notify)
  403. {
  404.    int res;
  405.    int size = 2;
  406.  
  407.    int ch = 0;      /* 0 == not child.. parent, 1 == child   */
  408.  
  409. #  ifndef NOSSL
  410.    int sslerr = 0;
  411.    int dobreak = 0;
  412. #  endif
  413.  
  414.    int first = 0;
  415.    int newdata = 0; /* indicate new data when oldbuf is null */
  416.  
  417.    char length[2];
  418.    char *lnptr, *cmdptr;
  419.  
  420.    if ((notify != 1) || (child != 1) || (clients[curClient].pinging != 1) ||
  421.        (clients[curClient].pidstats[1].pid <= 0)) notify = 0;
  422.  
  423.    if (notify == 1)
  424.    {
  425.       if (getpid() == clients[curClient].pidstats[0].pid) ch = 0;
  426.       else ch = 1;
  427.  
  428.       if (silent != 1) 
  429.          debug("(in %s) receiving data...\n", (ch == 1 ? "child" : "parent"));
  430.    }
  431.  
  432.    else if (silent != 1) debug("receiving data...\n");
  433.  
  434.    errno = errors = 0;
  435.    memset(readbuf, 0, len);
  436.  
  437.    if ((ch == 0) || (notify == 0)) /* in parent */
  438.    {
  439.       errno = 0;
  440.       lnptr = length, cmdptr = readbuf;
  441.  
  442.       size = 2;
  443.       while(1)
  444.       {
  445. #        ifndef NOSSL
  446.          res = SSL_read(clients[curClient].sslconn, lnptr, (u_int)size);
  447. #        else
  448.          res = read(clients[curClient].sockfd, lnptr, size);         
  449. #        endif
  450.  
  451.          /* ---------------------- */
  452.  
  453. #        ifndef NOSSL /* SSL error handling */
  454.          sslerr = SSL_get_error(clients[curClient].sslconn, res);
  455.          switch(sslerr)
  456.          {
  457.             case SSL_ERROR_NONE:
  458.                if (size == res) 
  459.                {
  460.                   dobreak = 1;
  461.                   break;
  462.                }
  463.  
  464.                lnptr += res, size -= res;
  465.                break;
  466.  
  467.             case SSL_ERROR_WANT_WRITE:
  468.             case SSL_ERROR_WANT_READ:
  469.             case SSL_ERROR_WANT_X509_LOOKUP:
  470.                errors = 1, dobreak = 1;
  471.                break;
  472.  
  473.             case SSL_ERROR_SYSCALL:
  474.             case SSL_ERROR_SSL:
  475.                errors = 1, dobreak = 1;
  476.                break;
  477.  
  478.             case SSL_ERROR_ZERO_RETURN:
  479.                errors = 1, dobreak = 1;
  480.                break;         
  481.          }
  482.  
  483.          if (dobreak == 1)
  484.          {
  485.             dobreak = 0;
  486.             break;
  487.          }
  488.          
  489. #        else /* no SSL error handling */
  490.          if (res <= 0)
  491.          {
  492.             if ((res == ERROR) && (errno == EINTR)) continue;
  493.  
  494.             errors = 1;
  495.             break;
  496.          }
  497.  
  498.          else if (res < size)
  499.          {
  500.             lnptr += res, size -= res;
  501.             continue;
  502.          }
  503.  
  504.          else break;
  505. #        endif /* SSL/NOSSL error handling */
  506.       }
  507.  
  508.       if (errors != 1)
  509.       {
  510.          /* clients[curClient].logmsg.cmdlen = importInt(length); */
  511.          clients[curClient].logmsg.cmdlen = importInt(lnptr);
  512.  
  513.          if (clients[curClient].logmsg.cmdlen > len - 1)
  514.          {
  515.             error("(in recv_data) cmdlen > buflen.. truncating\n\n");
  516.             clients[curClient].logmsg.cmdlen = len - 1;
  517.          }
  518.  
  519.          size = clients[curClient].logmsg.cmdlen;
  520.          while(1)
  521.          {
  522. #           ifndef NOSSL
  523.             res = SSL_read(clients[curClient].sslconn, cmdptr, (u_int)size);
  524. #           else
  525.             res = read(clients[curClient].sockfd, cmdptr, size);
  526. #           endif
  527.  
  528.             /* ---------------------- */
  529.  
  530. #           ifndef NOSSL /* SSL error handling */
  531.             sslerr = SSL_get_error(clients[curClient].sslconn, res);
  532.             switch(sslerr)
  533.             {
  534.                case SSL_ERROR_NONE:
  535.                   if (size == res) 
  536.                   {
  537.                      dobreak = 1;
  538.                      break;
  539.                   }
  540.  
  541.                   cmdptr += res, size -= res;
  542.                   break;
  543.  
  544.                case SSL_ERROR_WANT_WRITE:
  545.                case SSL_ERROR_WANT_READ:
  546.                case SSL_ERROR_WANT_X509_LOOKUP:
  547.                   errors = 1, dobreak = 1;
  548.                   break;
  549.  
  550.                case SSL_ERROR_SYSCALL:
  551.                case SSL_ERROR_SSL:
  552.                   errors = 1, dobreak = 1;
  553.                   break;
  554.  
  555.                case SSL_ERROR_ZERO_RETURN:
  556.                   errors = 1, dobreak = 1;
  557.                   break;         
  558.             }
  559.  
  560.             if (dobreak == 1)
  561.             {
  562.                dobreak = 0;
  563.                break;
  564.             }
  565.  
  566. #           else /* normal error handling */
  567.             if (res <= 0)
  568.             {
  569.                if ((res == ERROR) && (errno == EINTR)) continue;
  570.  
  571.                errors = 1;
  572.                break;
  573.             }
  574.  
  575.             else if (res < size)
  576.             {
  577.                cmdptr += res, size -= res;
  578.                continue;
  579.             }
  580.  
  581.             else break;
  582. #           endif /* SSL/NOSSL error handling */
  583.          }
  584.       }
  585.  
  586. #     ifndef NOSSL /* SSL error handling */
  587.       switch(sslerr)
  588.       {
  589.          case SSL_ERROR_NONE:
  590.             /* we don't need to do anything for this */
  591.             break;
  592.  
  593.          case SSL_ERROR_WANT_WRITE:
  594.          case SSL_ERROR_WANT_READ:
  595.          case SSL_ERROR_WANT_X509_LOOKUP:
  596.             error("got SSL_ERROR_WANT_(WRITE/READ/X509_LOOKUP).. "
  597.                   "ignoring\n\n");
  598.  
  599.             errors = 0;
  600.             break;
  601.  
  602.          case SSL_ERROR_SYSCALL:
  603.          case SSL_ERROR_SSL:
  604.             if (errno <= 0)
  605.             { 
  606.                errors = 0;
  607.                break;
  608.             }
  609.  
  610.             error("error with SSL_read: %s\n\n", strerror(errno));
  611.  
  612.             ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  613.             if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  614.  
  615.             if (mainpid != getpid()) quit(ERROR);
  616.             else
  617.             {
  618.                errors = 1, timeout = 0;
  619.                longjmp(newconn, 1);
  620.             }
  621.  
  622.          case SSL_ERROR_ZERO_RETURN:
  623.             if (mainpid != getpid())
  624.             {
  625.                error("client dropped connection.. aborting\n\n");
  626.                quit(ERROR);
  627.             }
  628.  
  629.             else
  630.             {
  631.                error("client dropped connection.. restarting\n\n");
  632.  
  633.                errors = 1, timeout = 0;
  634.                longjmp(newconn, 1);
  635.             }
  636.       }
  637.  
  638. #     else /* normal SSL error handling */
  639.       if (res <= 0)
  640.       {
  641.          if (res == 0)
  642.          {
  643.             if (getpid() != mainpid) 
  644.             {
  645.                error("the client disconnected.. aborting\n\n");
  646.                quit(ERROR);
  647.             }
  648.  
  649.             else
  650.             {
  651.                errors = 1;
  652.                error("the client disconnected.. restarting\n\n");
  653.                longjmp(newconn, 1);
  654.             }
  655.          }
  656.  
  657.          else if (errno > 0)
  658.          {
  659.             if ((debugging == 1) && (silent != 1))
  660.             {
  661.                (void)putchar('\n'); 
  662.                (void)write(dblogfd, "\n", 1);
  663.             }
  664.  
  665.             if (notify == 1)
  666.             {
  667. #              ifndef NOSSL
  668.                ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  669.                if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  670.  
  671. #              else
  672.                error("(in %s) error receiving data from client:\n%s\n\n", 
  673.                      (ch == 1 ? "child" : "parent"), strerror(errno));
  674. #              endif
  675.             }
  676.  
  677.             else
  678.             {
  679. #              ifndef NOSSL
  680.                ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  681.                if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  682.  
  683. #              else
  684.                error("error receiving data from client: %s\n\n", 
  685.                      strerror(errno));
  686. #              endif
  687.             }
  688.  
  689.             if (mainpid != getpid()) quit(ERROR);
  690.             else
  691.             {
  692.                errors = 1, timeout = 0;
  693.                longjmp(newconn, 1);
  694.             }
  695.          }
  696.  
  697.          else if ((errors == 1) || (timeout == 1))
  698.          {
  699.             if (silent != 1) 
  700.             {
  701. #              ifndef NOSSL
  702.                ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
  703.                if (debugging == 1) ERR_print_errors_fp(dblogfd1);
  704.  
  705. #              else
  706.                debug("(in recv_data) error or timeout receiving data\n");
  707. #              endif
  708.             }
  709.  
  710.             child = 0;
  711.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  712.  
  713.             if (mainpid != getpid()) quit(ERROR);
  714.             else
  715.             {
  716.                errors = 1, timeout = 0;
  717.                longjmp(newconn, 1);
  718.             }
  719.          }
  720.       }
  721. #     endif
  722.  
  723.       if (((readbuf[0] == '\n') || (readbuf[0] == '\0')) && 
  724.           (isprint(readbuf[1]) == 0))
  725.       {
  726. #        ifdef NOSSL
  727.          if (silent != 1)
  728.          {
  729.             if (child == 1)
  730.                debug("[in recv_data] (in %s)\n"
  731.                      "the data received is bad.. returning\n\n",
  732.                      (ch == 1 ? "child" : "parent"));
  733.  
  734.             else
  735.                debug("(in recv_data) the data received is bad.. "
  736.                      "returning\n\n");
  737.  
  738.             debug("bad data is:\n%s\n", readbuf);
  739.          }
  740.  
  741. #        else
  742.          error("client possibly disconnected.. aborting\n\n");
  743.  
  744.          if (mainpid != getpid()) quit(ERROR);
  745.          else 
  746.          {
  747.             errors = 1;
  748.             longjmp(newconn, 1);
  749.          }
  750. #        endif
  751.  
  752.          return;
  753.       }
  754.  
  755.       if (silent != 1)
  756.       {
  757.          if (notify == 1)
  758.          {
  759.             debug("(in %s) data received from the client\n",
  760.                   (ch == 1 ? "child" : "parent"));
  761.  
  762.             if (strlen(readbuf) > 30)
  763.                debug("(in %s) data is:\n%s\n%c", 
  764.                      (ch == 1 ? "child" : "parent"), readbuf,
  765.                      (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));
  766.  
  767.             else debug("(in %s) data is: %s%c", 
  768.                        (ch == 1 ? "child" : "parent"), readbuf, 
  769.                        (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));
  770.          }
  771.  
  772.          else
  773.          {
  774.             debug("data received from the client\n");
  775.  
  776.             if (strlen(readbuf) > 40)
  777.                debug("data is:\n%s\n%c", readbuf, 
  778.                      (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));
  779.  
  780.             else
  781.                debug("data is: %s%c", readbuf, 
  782.                      (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));
  783.          }
  784.       }
  785. /*
  786.       if (strncmp(readbuf, "OKAY", 4) != 0)
  787.       {
  788.          * (void)sleep(1); *
  789.  
  790.          * silent = 1, * send_data(clients[curClient].sockfd, "OKAY");
  791.          silent = 0;
  792.  
  793.          if ((errors == 1) || (timeout == 1))
  794.          {
  795.             child = 0;
  796.             send_data(clients[curClient].sockfd, "ERROR: %s\n", CMDACKERROR);
  797.  
  798.             if (getpid() != mainpid) quit(ERROR);
  799.             else
  800.             {
  801.                errors = 1, timeout = 0;
  802.                longjmp(newconn, 1);
  803.             }
  804.          }
  805.       }
  806.  
  807.       else */
  808.  
  809.       if ((strncmp(readbuf, "QUIT", 4) == 0)  || 
  810.           (strncmp(readbuf, "ERROR", 5) == 0))
  811.       {
  812.          if (mainpid != getpid()) signal(SIGPIPE, SIG_IGN);
  813.  
  814.          error("QUIT or ERROR received from client..\n"
  815.                "the message was: %s\n%c", readbuf,
  816.                (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));
  817.  
  818.          child = 0;
  819.  
  820.          if (mainpid != getpid()) quit(ERROR);
  821.          else 
  822.          {
  823.             errors = 1;
  824.             longjmp(newconn, 1);
  825.          }
  826.       }
  827.  
  828.       if (notify == 0) return; /* we don't need to do this if there */
  829.                                /* is no child to notify...          */
  830.  
  831.       if (clients[curClient].oldbuf[0] == '\0')
  832.       {
  833.          if (silent != 1)
  834.             debug("(in %s) no data in oldbuf.. putting data in\n",
  835.                   (ch == 1 ? "child" : "parent"));
  836.  
  837.          strncpy(clients[curClient].oldbuf, readbuf, 
  838.                  sizeof(clients[curClient].oldbuf));
  839.  
  840.          newdata = 1, first = 1;
  841.       }
  842.  
  843.       if (((newdata == 1) || 
  844.           (strcmp(clients[curClient].oldbuf, readbuf) != 0)) && 
  845.           ((strncmp(readbuf, "PONG", 4) == 0) || 
  846.           (strncmp(readbuf, "OKAY", 4) == 0)))
  847.       {
  848.          if ((debugging == 1) && (silent != 1))
  849.          {
  850.             (void)putchar('\n'); 
  851.             (void)write(dblogfd, "\n", 1);
  852.          }
  853.  
  854.          if (clients[curClient].running == 0)
  855.          {
  856.             if (silent != 1) debug("(in parent) running = 0, now waiting\n");
  857.             while (clients[curClient].running == 0) (void)sleep(1);
  858.          }
  859.  
  860.          /* new data has been receiveed */
  861.          if (silent != 1) debug("(in parent) sending SIGUSR1 to child\n");
  862.  
  863.          memset(clients[curClient].segptr, 0, MAXSEGSIZE);
  864.  
  865.          /* put it in shared mem */
  866.          (void)strncpy(clients[curClient].segptr, readbuf, MAXSEGSIZE-1); 
  867.          
  868.          if (silent != 1) 
  869.             debug("shared segment = %s%c", clients[curClient].segptr,
  870.                   (strchr(clients[curClient].segptr, '\n') == NULL 
  871.                           ? '\n' : '\0'));
  872.  
  873.          /* FIX - few problems.. first we could have missed any */
  874.          /*     - data we got as SIGUSR2 is on like always...   */
  875.  
  876.          clients[curClient].running = 0;
  877.          signal(SIGUSR2, startUp);
  878.  
  879.          res = seteuid(0); 
  880.          if (res == ERROR)
  881.          {
  882.             error("error with seteuid: %s\n\n", strerror(errno)); 
  883.             quit(ERROR);
  884.          }
  885.  
  886.          /* notify child there is new data */
  887.          res = kill(clients[curClient].pidstats[1].pid, SIGUSR1);
  888.          if (res == ERROR)
  889.          {
  890.             error("error sending SIGUSR1 to child:\n%s\n\n",
  891.                   strerror(errno));
  892.  
  893.             child = 0;
  894.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  895.  
  896.             res = seteuid(pwd->pw_uid);
  897.             if (res == ERROR)
  898.             {
  899.                error("error with seteuid: %s\n\n", strerror(errno)); 
  900.                quit(ERROR);
  901.             }
  902.  
  903.             if (mainpid != getpid()) quit(ERROR);
  904.             else
  905.             {
  906.                errors = 1;
  907.                longjmp(newconn, 1);
  908.             }
  909.          }
  910.  
  911.          res = seteuid(pwd->pw_uid);
  912.          if (res == ERROR)
  913.          {
  914.             error("error with seteuid: %s\n\n", strerror(errno)); 
  915.             quit(ERROR);
  916.          }
  917.  
  918.          if ((debugging == 1) && (silent != 1))
  919.          {
  920.             (void)putchar('\n'); 
  921.             (void)write(dblogfd, "\n", 1);
  922.          }
  923.  
  924.          /* while (clients[curClient].running == 0) sleep(1); */
  925.  
  926.          return;
  927.       }
  928.  
  929.       else
  930.       {
  931.          if ((silent != 1) && (first != 1))
  932.             debug("(in %s) new data was duplicate data.. ignoring\n",
  933.                   (ch == 1 ? "child" : "server"));
  934.  
  935.          else first = 0;
  936.  
  937.          return;
  938.       }
  939.    }
  940.  
  941.    else /* if (ch == 1) */
  942.    {
  943.       if (clients[curClient].newData != 1)
  944.       {
  945.          if (silent != 1) debug("(in child) newData = 0, now waiting\n");
  946.          while (clients[curClient].newData == 0) sleep(NORMPAUSE);
  947.       }
  948.  
  949.       errno = 0;
  950.       if ((debugging == 1) && (silent != 1))
  951.       {
  952.          (void)putchar('\n'); 
  953.          (void)write(dblogfd, "\n", 1);
  954.       }
  955.  
  956.       /* make sure buffer is blank */
  957.       memset(readbuf, 0, len);
  958.  
  959.       if (silent != 1)
  960.          debug("shared segment = %s%c", clients[curClient].segptr,
  961.               (strchr(clients[curClient].segptr, '\n') == NULL ? '\n' : '\0'));
  962.  
  963.       memcpy(readbuf, clients[curClient].segptr, len), readbuf[len] = '\0';
  964.  
  965.       if (silent != 1)
  966.          debug("readbuf (after copying seg) = %s%c", readbuf,
  967.               (strchr(clients[curClient].segptr, '\n') == NULL ? '\n' : '\0'));
  968.  
  969.       clients[curClient].newData = 0; /* reset new data marker */
  970.  
  971.       res = seteuid(0);
  972.       if (res == ERROR)
  973.       {
  974.          error("error with seteuid: %s\n\n", strerror(errno)); 
  975.          quit(ERROR);
  976.       }
  977.  
  978.       /* tell parent we got data.. it can continue */
  979.       res = kill(clients[curClient].pidstats[0].pid, SIGUSR2);
  980.       if (res == ERROR)
  981.       {
  982.          child = 0;
  983.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  984.  
  985.          res = seteuid(pwd->pw_uid);
  986.          if (res == ERROR)
  987.          {
  988.             error("error with seteuid: %s\n\n", strerror(errno)); 
  989.             quit(ERROR);
  990.          }
  991.  
  992.          if (mainpid != getpid()) quit(ERROR);
  993.          else
  994.          {
  995.             errors = 1;
  996.             longjmp(newconn, 1);
  997.          }
  998.       }
  999.  
  1000.       res = seteuid(pwd->pw_uid);
  1001.       if (res == ERROR)
  1002.       {
  1003.          error("error with seteuid: %s\n\n", strerror(errno)); 
  1004.          quit(ERROR);
  1005.       }
  1006.  
  1007.       return;
  1008.    }
  1009. }
  1010.